package com.ziytek.web.citizen.listener;

import com.google.gson.Gson;
import com.ziytek.web.citizen.caffeine.CachePutOrGet;
import com.ziytek.web.citizen.config.caffeine.CaffeineUtil;
import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.enums.ErrorTypeEnum;
import com.ziytek.web.citizen.event.CommandIssuedEndEvent;
import com.ziytek.web.citizen.mapper.OperationDetailMapper;
import com.ziytek.web.citizen.mapper.SettingDetailMapper;
import com.ziytek.web.citizen.model.bean.CommandIssuedSuccess;
import com.ziytek.web.citizen.model.vo.OperationVo;
import com.ziytek.web.citizen.service.OperationVoCacheService;
import com.ziytek.web.citizen.util.KeyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

/**
 * 工步指令执行结果事件
 *
 * @author fengh
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CommandIssuedEndEventListener {
    private final Gson gson;
    private final CachePutOrGet cachePutOrGet;
    private final SettingDetailMapper settingDetailMapper;
    private final OperationDetailMapper operationDetailMapper;
    private final OperationVoCacheService operationVoCacheService;

    @Async("myAsyncExecutor")
    @EventListener
    @Order(ServerConstant.DATA_TYPE_LEN_1)
    public void commandIssuedEndEventListener(CommandIssuedEndEvent event) {
        Assert.notNull(event, "commandIssuedEndEventListener event is null");
        Assert.notNull(event.getCommand(), "commandIssuedEndEventListener command is null");
        Assert.notNull(event.getCommand().getOrder(), "commandIssuedEndEventListener command order is null");

        var command = event.getCommand();
        log.info("工步执行完成结束,事件处理commandIssuedEndEventListener:{}", command);

        var order = command.getOrder();
        var sd = settingDetailMapper.queryListByStepIdDesc(command.getStepId());
        if (sd == null || sd.getIsDelete() == null) {
            //log.info("commandIssuedEndEventListener,settingDetail is null,stepId:{}", command.getStepId());
            return;
        }

        var lastOrder = sd.getSettingOrder();
        // todo 最后一个工步方案已经执行结束 ,导出分容统计数据表报
        if (order - NumConstant.INT_ONE == lastOrder) {
            log.info("最后一个工步步骤,工步执行完成储存容量数据commandIssuedEndEventListener, last step is executed finished,stepId:{}", command.getStepId());
            // 单个通道工步方案执行结束，导出分容统计数据表报(统一导出一个Excel报表)
            if (command.isSingleChannel()) {
                singleStats(command, command.getBoardNo());
                return;
            }

            // 整体工艺完成的，修改工艺状态为完成
            allChannelStats(command);

            // todo 导出分容统计数据表报
            exportData(Integer.parseInt(command.getReqCabinetNo()));
        }
    }

    private void singleStats(CommandIssuedSuccess command, int boardNo) {

        // 修改通道工步操作记录状态为已完成状态
        var cabinetNo = String.valueOf(Integer.parseInt(String.valueOf(command.getReqCabinetNo())));
        var od = operationDetailMapper.findOneDetailByCellNum(cabinetNo, command.getBoardNo(), command.getChannelNo());
        if (null != od) {
            //if (ServerConstant.START_FLAG_ERROR != od.getStartFlag()) {
            // od.setStartFlag(ServerConstant.START_FLAG_FINISH);
            // }
            //od.setUpdateTime(System.currentTimeMillis());
            //operationDetailMapper.updateDetail(od);

            // 删除数据
            //operationDetailMapper.deleteDetail(od);
            CaffeineUtil.set(CaffeineUtil.OPERATION_DETAIL_DEL_KEY + gson.toJson(command), od, 3);
        }

        // 单个通道工步方案执行结束，导出分容统计数据表报(统一导出一个Excel报表)
        log.info("最后一个工步步骤,工步执行完成单通道容量数据储存commandIssuedEndEventListener, singleStats boardNo:{}", boardNo);
        // 修改单个工艺状态为完成
        var key = command.getReqCabinetNo() + CaffeineUtil.CACHE_KEY_SYMBOL + command.getBoardNo() + CaffeineUtil.CACHE_KEY_SYMBOL + command.getChannelNo();
        var s = cachePutOrGet.getStatsCache(key);

        var opKey = KeyUtil.commandOperateKey(command.getReqCabinetNo(), command.getBoardNo(), command.getChannelNo());
        OperationVo vo = operationVoCacheService.getOperationVo(opKey);
        if (vo != null) {
            // 状态正常才设置状态为已完成
            if (ServerConstant.START_FLAG_NORMAL == vo.getStartFlag()) {
                vo.setStartFlag(ServerConstant.START_FLAG_FINISH);
            }
            // 设置缓存时间
            operationVoCacheService.putOperationVo(opKey, vo);
        }

        // 待工艺或者空闲的不修改状态
        var isWait = s == null || s.getT() == ErrorTypeEnum.WAITING.getCode() || s.getT() == ErrorTypeEnum.LEISURE.getCode();
        if (isWait) {
            return;
        }

        // 状态为执行中才设置状态为已完成
        if (ErrorTypeEnum.EXECUTING.getCode() == s.getT()) {
            s.setT(ErrorTypeEnum.EXECUTION_COMPLETED.getCode());
        }
        // 设置缓存时间
        CaffeineUtil.set(CaffeineUtil.STATS_CACHE_PREFIX + key, s, 24 * 60 * 60 * 60);

//        // 修改通道工步操作记录状态为已完成状态
//        var cabinetNo = String.valueOf(Integer.parseInt(String.valueOf(command.getReqCabinetNo())));
//        var od = operationDetailMapper.findOneDetailByCellNum(cabinetNo, command.getBoardNo(), command.getChannelNo());
//        if (null != od) {
//            //if (ServerConstant.START_FLAG_ERROR != od.getStartFlag()) {
//            // od.setStartFlag(ServerConstant.START_FLAG_FINISH);
//            // }
//            //od.setUpdateTime(System.currentTimeMillis());
//            //operationDetailMapper.updateDetail(od);
//
//            // 删除数据
//            operationDetailMapper.deleteDetail(od);
//        }

        // todo 导出分容统计数据表报
    }

    private void allChannelStats(CommandIssuedSuccess command) {
        // 整体工艺完成的，修改工艺状态为完成
        var cabinetNo = String.valueOf(Integer.parseInt(String.valueOf(command.getReqCabinetNo())));
        var operationDetailList = operationDetailMapper.findDetailNotSingleType(cabinetNo, ServerConstant.SINGLE_TYPE_ALL);
        log.info("完成operationDetailList：{}", operationDetailList.size());
        if (CollectionUtils.isEmpty(operationDetailList)) {
            return;
        }

        for (var od : operationDetailList) {
            // 删除数据
            //operationDetailMapper.deleteDetail(od);
            CaffeineUtil.set(CaffeineUtil.OPERATION_DETAIL_DEL_KEY + gson.toJson(od), od, 3);

            var key = command.getReqCabinetNo() + CaffeineUtil.CACHE_KEY_SYMBOL + od.getBoardAddress() + CaffeineUtil.CACHE_KEY_SYMBOL + od.getCellNum();
            var s = cachePutOrGet.getStatsCache(key);
            var opKey = KeyUtil.commandOperateKey(command.getReqCabinetNo(), od.getBoardAddress(), od.getCellNum());
            OperationVo vo = operationVoCacheService.getOperationVo(opKey);
            //log.info("完成查询缓存:{}", vo == null);
            if (vo != null) {
                // 状态正常才设置状态为已完成
                if (ServerConstant.START_FLAG_NORMAL == vo.getStartFlag() || ServerConstant.START_FLAG_FINISH == vo.getStartFlag()) {
                    //log.info("修改完成状态：{}", opKey);
                    vo.setStartFlag(ServerConstant.START_FLAG_FINISH);
                }
                // 设置缓存时间
                operationVoCacheService.putOperationVo(opKey, vo);
            }

            // 待工艺或者空闲的不修改状态
            var isWait = s == null || (s.getT() == ErrorTypeEnum.WAITING.getCode() || s.getT() == ErrorTypeEnum.LEISURE.getCode());
            if (isWait) {
                log.info("不能修改完成状态：{}", opKey);
                continue;
            }

            // 状态为执行中才设置状态为已完成
            if (ErrorTypeEnum.EXECUTING.getCode() == s.getT()) {
                s.setT(ErrorTypeEnum.EXECUTION_COMPLETED.getCode());
            }
            CaffeineUtil.set(CaffeineUtil.STATS_CACHE_PREFIX + key, s, 24 * 60 * 60 * 60);

            // 修改通道工步操作记录状态为已完成状态
            //if (ServerConstant.START_FLAG_ERROR != od.getStartFlag()) {
            //od.setStartFlag(ServerConstant.START_FLAG_FINISH);
            //}
            //od.setUpdateTime(System.currentTimeMillis());
            //operationDetailMapper.updateDetail(od);

            log.info("最后一个工步步骤,工步执行完成全部通道容量数据储存,修改完成状态：{}", opKey);
        }
    }

    private void exportData(int cabinetNo) {

        // 全局指令下发
        // 查询配置，不同版本对应机柜门机通道总数(一个机柜门对应4个恒流板，一个板子对应8个通道，总共32个通道)
//        List<DoorConfig> doors = doorsService.getDoorsConfig();
//        Assert.notEmpty(doors, "CommandIssuedSuccess doors is empty");
//
//
    }

}
